﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Xml;
using System.IO;
namespace Synchros
{
    public class XmlHelper
    {

        private static readonly string strXmlCfgPath = System.Windows.Forms.Application.StartupPath + "\\Synchros.xml";

        //ggz:检查创建XML配置文件
        public static void CheckConfigExist()
        {
            try
            {
                XmlDocument document = new XmlDocument();
                try
                {
                    document.Load(strXmlCfgPath);
                }
                catch
                {
                    document.AppendChild(document.CreateNode(XmlNodeType.XmlDeclaration, "", ""));
                    document.AppendChild(document.CreateElement("Config"));
                    document.DocumentElement.AppendChild(document.CreateElement("Conns"));
                    document.DocumentElement.AppendChild(document.CreateElement("Syncs"));
                    document.Save(strXmlCfgPath);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //ggz:加载连接配置
        public static void FillConnConfig(DataTable dt)
        {
            if (dt == null) throw new Exception();
            if (dt.Columns.Count == 0)
            {
                //构建Table
                dt.Columns.Add("Server");
                dt.Columns.Add("UserID");
                dt.Columns.Add("Password");
            }
            else if (dt.Rows.Count > 0)
            {
                dt.Clear();
            }

            //加载xml
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(strXmlCfgPath);
                XmlNodeList nodeList = doc.DocumentElement["Conns"].ChildNodes;
                DataRow dr = null;
                for (int i = 0; i < nodeList.Count; i++)
                {
                    dr = dt.NewRow();
                    dr["Server"] = nodeList[i].Attributes["Name"].Value;
                    dr["UserID"] = nodeList[i]["UserID"].InnerText;
                    dr["Password"] = nodeList[i]["Password"].InnerText;
                    dt.Rows.Add(dr);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        //ggz:保存连接配置
        public static bool SaveConnConfig(DataTable dt)
        {
            try
            {
                //if (!File.Exists(strXmlCfgPath)) CreatestrCfg(strXmlCfgPath);
                XmlDocument doc = new XmlDocument();
                doc.Load(strXmlCfgPath);
                XmlNode nodeConns = doc.DocumentElement["Conns"];
                nodeConns.RemoveAll();
                for(int i=0;i<dt.Rows.Count;i++)
                {
                    XmlElement eleServer = doc.CreateElement("Server");

                    XmlAttribute attName = doc.CreateAttribute("Name");
                    attName.Value= dt.Rows[i]["Server"].ToString();

                    XmlElement eleUserID = doc.CreateElement("UserID");
                    eleUserID.InnerText = dt.Rows[i]["UserID"].ToString();

                    XmlElement elePassword = doc.CreateElement("Password");
                    elePassword.InnerText = dt.Rows[i]["Password"].ToString();

                    eleServer.Attributes.Append(attName);
                    eleServer.AppendChild(eleUserID);
                    eleServer.AppendChild(elePassword);
                    nodeConns.AppendChild(eleServer);
                }
                doc.Save(strXmlCfgPath);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //ggz:加载同步配置
        public static void FillSyncConfig(List<SyncItem> lstSync)
        {
            try
            {
                FillSyncConfig(lstSync, false);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static void FillSyncConfig(List<SyncItem> lstSync,bool isSync)
        {
            string strServer = string.Empty;
            string strUserID = string.Empty;
            string strPassword = string.Empty;
            try
            {
                lstSync.Clear();
                XmlDocument doc = new XmlDocument();
                doc.Load(strXmlCfgPath);
                XmlNodeList nodeListGroup = doc.DocumentElement["Syncs"].ChildNodes;
                for (int iGroup = 0; iGroup < nodeListGroup.Count; iGroup++)
                {
                    // 只取同步 组不同步时 下一个
                    if (isSync) if (!Convert.ToBoolean(nodeListGroup[iGroup].Attributes["IsSync"].Value)) continue;

                    SyncItem syncitem = new SyncItem();
                    syncitem.SgName = nodeListGroup[iGroup].Attributes["SgName"].Value;
                    syncitem.Spaced = Convert.ToInt32(nodeListGroup[iGroup].Attributes["Spaced"].Value);
                    syncitem.IsSync = Convert.ToBoolean(nodeListGroup[iGroup].Attributes["IsSync"].Value);

                    #region 获取同步库配置
                    syncitem.SyncDb.Clear();                    
                    XmlNodeList nodeListSyncDb=nodeListGroup[iGroup]["Databases"].ChildNodes;
                    for (int iSyncDb = 0; iSyncDb < nodeListSyncDb.Count; iSyncDb++)
                    {
                        // 只取同步 库不同步时 下一个
                        if (isSync) if (!Convert.ToBoolean(nodeListSyncDb[iSyncDb].Attributes["IsSync"].Value)) continue;

                        DataRow drSyncDb = syncitem.SyncDb.NewRow();
                        {
                            drSyncDb["SdName"] = nodeListSyncDb[iSyncDb].Attributes["SdName"].Value;
                            drSyncDb["IsMain"] = Convert.ToBoolean(nodeListSyncDb[iSyncDb].Attributes["IsMain"].Value);
                            drSyncDb["IsSync"] = Convert.ToBoolean(nodeListSyncDb[iSyncDb].Attributes["IsSync"].Value);
                            drSyncDb["SdTime"] = nodeListSyncDb[iSyncDb].Attributes["SdTime"].Value;
                            strServer = nodeListSyncDb[iSyncDb]["Server"].InnerText;
                            ConfigureConnectionInfo(strServer, ref strUserID, ref strPassword);

                            drSyncDb["Server"] = strServer;
                            drSyncDb["Database"] = nodeListSyncDb[iSyncDb]["Database"].InnerText;
                            drSyncDb["UserID"] = strUserID;
                            drSyncDb["Password"] = strPassword;
                        }
                        syncitem.SyncDb.Rows.Add(drSyncDb);
                    }
                    #endregion

                    #region 获取同步表配置
                    syncitem.SyncTb.Clear();
                    XmlNodeList nodeListSyncTb = nodeListGroup[iGroup]["Tables"].ChildNodes;
                    for (int iSyncTb = 0; iSyncTb < nodeListSyncTb.Count; iSyncTb++)
                    {
                        // 只取同步 表不同步时 下一个
                        if (isSync) if (!Convert.ToBoolean(nodeListSyncTb[iSyncTb].Attributes["IsSync"].Value)) continue;
                        DataRow drSyncTb = syncitem.SyncTb.NewRow();
                        {
                            drSyncTb["StName"] = nodeListSyncTb[iSyncTb].Attributes["StName"].Value;
                            drSyncTb["IsSync"] = Convert.ToBoolean(nodeListSyncTb[iSyncTb].Attributes["IsSync"].Value);
                            drSyncTb["StTime"] = nodeListSyncTb[iSyncTb].Attributes["StTime"].Value;

                            #region 获取表中列配置
                            XmlNodeList nodeListColumn = nodeListSyncTb[iSyncTb].ChildNodes;
                            DataTable dtColumn = SyncItem.CreateColumnTable();
                            for (int iColumn = 0; iColumn < nodeListColumn.Count; iColumn++)
                            {
                                DataRow drColumn = dtColumn.NewRow();
                                {
                                    drColumn["ScName"] = nodeListColumn[iColumn].Attributes["ScName"].Value;
                                    drColumn["ScType"] = nodeListColumn[iColumn].Attributes["ScType"].Value;
                                    drColumn["ScSize"] = nodeListColumn[iColumn].Attributes["ScSize"].Value;
                                    drColumn["ScPkey"] = nodeListColumn[iColumn].Attributes["ScPkey"].Value;
                                    drColumn["ScIdtt"] = nodeListColumn[iColumn].Attributes["ScIdtt"].Value;
                                    drColumn["DeOnly"] = nodeListColumn[iColumn].Attributes["DeOnly"].Value;
                                }
                                dtColumn.Rows.Add(drColumn);
                            }
                            drSyncTb["Column"] = dtColumn;
                            #endregion
                        }
                        syncitem.SyncTb.Rows.Add(drSyncTb);
                    }
                    #endregion

                    // 同步库少于两个时,该组不同步
                    if (isSync) if (syncitem.SyncDb.Rows.Count < 2) continue;
                    // 同步表少于一张时,该组不同步
                    if (isSync) if (syncitem.SyncTb.Rows.Count < 1) continue;

                    // 添加到同步
                    lstSync.Add(syncitem);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //ggz:保存同步配置
        public static bool SaveSyncConfig(List<SyncItem> lstSync)
        {//DataTable dtSyncGp,DataTable dtSyncDb,DataTable dtSyncTb
            try
            {
                //if (!File.Exists(strXmlCfgPath)) CreatestrCfg(strXmlCfgPath);
                XmlDocument doc = new XmlDocument();
                doc.Load(strXmlCfgPath);
                XmlNode nodeSyncs = doc.DocumentElement["Syncs"];
                nodeSyncs.RemoveAll();//先清空
                for (int iGroup = 0; iGroup < lstSync.Count; iGroup++)
                {
                    XmlElement eleSyncGp = doc.CreateElement("SyncGp");
                    {
                        XmlAttribute attSgName = doc.CreateAttribute("SgName");
                        attSgName.Value = lstSync[iGroup].SgName;
                        XmlAttribute attSpaced = doc.CreateAttribute("Spaced");
                        if (lstSync[iGroup].Spaced > 10)//同步间隔至少为10秒
                        {
                            attSpaced.Value = lstSync[iGroup].Spaced.ToString();
                        }
                        else
                        {
                            attSpaced.Value = "10";
                        }

                        XmlAttribute attIsSync = doc.CreateAttribute("IsSync");
                        attIsSync.Value = lstSync[iGroup].IsSync.ToString();

                        XmlElement eleDatabases = doc.CreateElement("Databases");
                        DataTable dtSyncDb = lstSync[iGroup].SyncDb;
                        for (int iSyncDb = 0; iSyncDb < dtSyncDb.Rows.Count; iSyncDb++)
                        {
                            XmlElement eleSyncDb = doc.CreateElement("SyncDb");
                            {
                                XmlAttribute attSyncDbName = doc.CreateAttribute("SdName");
                                attSyncDbName.Value = dtSyncDb.Rows[iSyncDb]["SdName"].ToString();

                                XmlAttribute attSyncDbIsSync = doc.CreateAttribute("IsSync");
                                string strSyncDbIsIsSync = dtSyncDb.Rows[iSyncDb]["IsSync"].ToString();
                                attSyncDbIsSync.Value = (strSyncDbIsIsSync != "" && Convert.ToBoolean(strSyncDbIsIsSync)).ToString();

                                XmlAttribute attSyncDbIsMain = doc.CreateAttribute("IsMain");
                                string strSyncDbIsMain = dtSyncDb.Rows[iSyncDb]["IsMain"].ToString();
                                attSyncDbIsMain.Value = (strSyncDbIsMain != "" && Convert.ToBoolean(strSyncDbIsMain)).ToString();

                                XmlAttribute attSyncDbSdTime = doc.CreateAttribute("SdTime");
                                attSyncDbSdTime.Value = dtSyncDb.Rows[iSyncDb]["SdTime"].ToString();

                                XmlElement eleServer = doc.CreateElement("Server");
                                eleServer.InnerText = dtSyncDb.Rows[iSyncDb]["Server"].ToString(); 
                                XmlElement eleDatabase = doc.CreateElement("Database");
                                eleDatabase.InnerText = dtSyncDb.Rows[iSyncDb]["Database"].ToString();

                                eleSyncDb.Attributes.Append(attSyncDbName);
                                eleSyncDb.Attributes.Append(attSyncDbIsSync);
                                eleSyncDb.Attributes.Append(attSyncDbIsMain);
                                eleSyncDb.Attributes.Append(attSyncDbSdTime);
                                eleSyncDb.AppendChild(eleServer);
                                eleSyncDb.AppendChild(eleDatabase);
                                eleDatabases.AppendChild(eleSyncDb);
                            }
                            eleDatabases.AppendChild(eleSyncDb);
                        }

                        XmlElement eleTables = doc.CreateElement("Tables");
                        DataTable dtSyncTb = lstSync[iGroup].SyncTb;
                        for (int iSyncTb = 0; iSyncTb < dtSyncTb.Rows.Count; iSyncTb++)
                        {
                            XmlElement eleSyncTb = doc.CreateElement("SyncTb");
                            {
                                XmlAttribute attSyncTbName = doc.CreateAttribute("StName");
                                attSyncTbName.Value = dtSyncTb.Rows[iSyncTb]["StName"].ToString();
                                XmlAttribute attSyncDbIsSync = doc.CreateAttribute("IsSync");
                                string strSyncDbIsSync = dtSyncTb.Rows[iSyncTb]["IsSync"].ToString();
                                attSyncDbIsSync.Value = (strSyncDbIsSync != "" && Convert.ToBoolean(strSyncDbIsSync)).ToString();

                                XmlAttribute attSyncTbTime = doc.CreateAttribute("StTime");

                                object ojbStTime = dtSyncTb.Rows[iSyncTb]["StTime"];
                                if (ojbStTime != DBNull.Value && ojbStTime != null && ojbStTime.ToString().Trim()!="")
                                {
                                    attSyncTbTime.Value = Convert.ToDateTime(ojbStTime).ToString("yyyy-MM-dd HH:mm:ss.fff");
                                }
                                
                                eleSyncTb.Attributes.Append(attSyncTbName);
                                eleSyncTb.Attributes.Append(attSyncDbIsSync);

                                eleSyncTb.Attributes.Append(attSyncTbTime);

                                DataTable dtColumn=dtSyncTb.Rows[iSyncTb]["Column"] as DataTable;
                                for (int iColumn = 0; iColumn < dtColumn.Rows.Count; iColumn++)
                                {
                                    XmlElement eleColumn = doc.CreateElement("Column");
                                    {
                                        XmlAttribute attScName = doc.CreateAttribute("ScName");
                                        attScName.Value = dtColumn.Rows[iColumn]["ScName"].ToString();
                                        eleColumn.Attributes.Append(attScName);
                                    }
                                    {
                                        XmlAttribute attScType = doc.CreateAttribute("ScType");
                                        attScType.Value = dtColumn.Rows[iColumn]["ScType"].ToString();
                                        eleColumn.Attributes.Append(attScType);
                                    }
                                    {
                                        XmlAttribute attScSize = doc.CreateAttribute("ScSize");
                                        attScSize.Value = dtColumn.Rows[iColumn]["ScSize"].ToString();
                                        eleColumn.Attributes.Append(attScSize);
                                    }
                                    {
                                        XmlAttribute attScPkey = doc.CreateAttribute("ScPkey");
                                        string strScPkey = dtColumn.Rows[iColumn]["ScPkey"].ToString();
                                        attScPkey.Value = (strScPkey != "" && Convert.ToBoolean(strScPkey)).ToString();
                                        eleColumn.Attributes.Append(attScPkey);
                                    }
                                    {
                                        XmlAttribute attScIdtt = doc.CreateAttribute("ScIdtt");
                                        string strScIdtt = dtColumn.Rows[iColumn]["ScIdtt"].ToString();
                                        attScIdtt.Value = (strScIdtt != "" && Convert.ToBoolean(strScIdtt)).ToString();
                                        eleColumn.Attributes.Append(attScIdtt);
                                    }
                                    {
                                        XmlAttribute attDeOnly = doc.CreateAttribute("DeOnly");
                                        string strDeOnly = dtColumn.Rows[iColumn]["DeOnly"].ToString();
                                        attDeOnly.Value = (strDeOnly != "" && Convert.ToBoolean(strDeOnly)).ToString();
                                        eleColumn.Attributes.Append(attDeOnly);
                                    }
                                    
                                    eleSyncTb.AppendChild(eleColumn);
                                }
                            }
                            eleTables.AppendChild(eleSyncTb);
                        }

                        eleSyncGp.Attributes.Append(attSgName);
                        eleSyncGp.Attributes.Append(attSpaced);
                        eleSyncGp.Attributes.Append(attIsSync);

                        eleSyncGp.AppendChild(eleDatabases);
                        eleSyncGp.AppendChild(eleTables);
                    }
                    nodeSyncs.AppendChild(eleSyncGp);
                }
                doc.Save(strXmlCfgPath);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //根据服务器名获取数据连接的用户名和密码
        public static void ConfigureConnectionInfo(string strServer, ref string strUserID, ref string strPassword)
        {
            //加载xml
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(strXmlCfgPath);
                XmlNodeList nodeList = doc.DocumentElement["Conns"].ChildNodes;
                for (int i = 0; i < nodeList.Count; i++)
                {
                    if (nodeList[i].Attributes["Name"].Value == strServer)
                    {
                        strUserID = nodeList[i]["UserID"].InnerText;
                        strPassword = nodeList[i]["Password"].InnerText;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
